package com.kgc.controller;

import com.kgc.common.Result;
import com.kgc.entity.FilesOss;
import com.kgc.service.interf.FilesOssService;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

@RestController
@RequestMapping("/apis/user/file")
public class FilesOssActionController {

    @Autowired
    private FilesOssDemoController filesOssDemoController;//oss

    @Autowired
    private FilesOssService filesOssService;//数据库

    /**
     * 头像上传
     *
     * @param imageFile
     * @param userId
     * @param identityType
     * @return
     * @throws IOException
     */
    @RequestMapping("/image/avatar/upload")
    public String uploadFile(MultipartFile imageFile, Integer userId, Integer identityType) throws IOException {
        try {
            // 获取上传文件的大小（以字节为单位）
            long fileSizeInBytes = imageFile.getSize();
            // 设置最大允许的文件大小（以字节为单位），目前设定为 1 MB
            final long MAX_FILE_SIZE_MB = 1;
            final long MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
            // 检查文件大小是否超过限制，若超过则抛出 IllegalArgumentException
            if (fileSizeInBytes > MAX_FILE_SIZE_BYTES) {
                throw new IllegalArgumentException("上传文件过大！最大允许的文件大小为 " + MAX_FILE_SIZE_MB + " MB");
            }
            //如果imageFile为空 返回错误信息
            if (imageFile.isEmpty()) {
                return Result.success("400", "文件上传失败");
            }
            //upload返回值有上传用户id 文件路径
            String fileName = filesOssDemoController.upload(imageFile);
            //上传数据库
            int i = filesOssService.upload(fileName, userId, identityType);
            if (i > 0) {
                return Result.success("0", "文件上传成功", fileName);
            } else {
                return Result.success("400", "文件上传失败");
            }
        } catch (IllegalArgumentException e) {
            return Result.success("400", "文件大小超过限制");
        }
    }

    /**
     * 图片上传 不到数据库
     *
     * @throws IOException
     */
    @RequestMapping("/image/avatar/img")
    public String uploadImg(MultipartFile imageFile) throws IOException {
        try {
            // 获取上传文件的大小（以字节为单位）
            long fileSizeInBytes = imageFile.getSize();
            // 设置最大允许的文件大小（以字节为单位），目前设定为 1 MB
            final long MAX_FILE_SIZE_MB = 1;
            final long MAX_FILE_SIZE_BYTES = MAX_FILE_SIZE_MB * 1024 * 1024;
            // 检查文件大小是否超过限制，若超过则抛出 IllegalArgumentException
            if (fileSizeInBytes > MAX_FILE_SIZE_BYTES) {
                throw new IllegalArgumentException("上传文件过大！最大允许的文件大小为 " + MAX_FILE_SIZE_MB + " MB");
            }
            //如果imageFile为空 返回错误信息
            if (imageFile.isEmpty()) {
                return Result.success("400", "文件上传失败");
            }
            String fileName = filesOssDemoController.upload(imageFile);
            return Result.success("0", "文件上传成功", fileName);
        } catch (IllegalArgumentException e) {
            return Result.success("400", "文件大小超过限制");
        }
    }


    /**
     * 文件上传 支持多文件上传
     * 利用阿里云的安全产品绿网来进行文件内容审查
     *
     * @param file
     * @param userId
     * @return
     * @throws IOException
     */
    @RequestMapping("/resource/upload")
    public String upload(MultipartFile[] file, Integer userId) throws IOException {
        for (int i = 0; i < file.length; i++) {
            if (file != null) {
                //设置文件上传路径
                String path = "E:\\Mycode\\blog_system\\src\\main\\webapp\\file";
                //设置上传文件名(防止重名,获取文件类型)
                //获取文件名
                String oldFilename = file[i].getOriginalFilename();
                //获取文件类型
                String type = FilenameUtils.getExtension(oldFilename);
                //使用当前时间作为新的文件名
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
                String newFilename = sdf.format(date) + "." + type;
                //配置文件路径 分隔符separator
                String picPath = path + File.separator + newFilename;
                //限制上传文件的大小和类型
                int fileSize = 100000;
                if (file[i].getSize() > fileSize) {
                    return Result.success("100", "文件大小超过限制");
                } else if (!"jpg,jpeg,png,bmp,zip,txt,RAR".contains(type)) {//是否包含制定元素contains
                    return Result.success("200", "仅支持压缩包格式");
                } else {
                    File newFile = new File(picPath);
                    file[i].transferTo(newFile);

                    FilesOss filesOss = new FilesOss();
                    filesOss.setFileName(newFilename);
                    filesOss.setFilePath(picPath);
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss ");
                    filesOss.setUploadedAt(simpleDateFormat.format(new Date()));
                    filesOss.setUserID(userId);
                    int i1 = filesOssService.upload(filesOss);
                    if (i1 > 0) {
                        return Result.success("0", "文件上传成功");
                    } else {
                        return Result.success("400", "参数不合法");
                    }
                }

            }
        }
        return Result.success("0", "文件上传成功");
    }


    /**
     * 文件下载
     * 根据id查询下载
     *
     * @param fileId
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("/download")
    public String down(HttpServletResponse response, Integer fileId) throws IOException {
        //获取文件名
        String filename = filesOssService.down(fileId);
        System.out.println("文件名" + filename);
        // 创建输入流和输出流
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        // 指定文件所在的路径
        String path = "E:\\Mycode\\blog_system\\src\\main\\webapp\\file";
        // 完整的文件路径
        String filePath = path + "\\" + File.separator + filename;

        // 创建文件对象
        File file = new File(filePath);
        // 设置响应头，指定文件名  指定文件应作为附件下载，并指定下载后的文件名。
        response.addHeader("Content-Disposition", "attachment;filename=" + filename);
        // 设置响应头，指定文件类型 表明发送的是原始二进制数据，通常会导致浏览器以下载附件的形式处理。
        response.setContentType("application/octet-stream");
        // 设置响应头，指定文件大小 提供文件的大小信息，帮助客户端准确管理下载过程。
        response.addHeader("Content-Length", String.valueOf(file.length()));

        try {
            // 创建输入流，读取文件
            bis = new BufferedInputStream(new FileInputStream(file));
            // 创建输出流，写入响应流
            bos = new BufferedOutputStream(response.getOutputStream());
            // 创建缓冲区
            byte[] buff = new byte[1024];
            // 每次读取的字节数
            int len;
            // 当读取的字节数不为-1时，循环读取
            while ((len = bis.read(buff)) != -1) {
                // 将读取的字节数写入响应流
                bos.write(buff, 0, len);
            }
            return Result.success("0", "文件正在下载");
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
            return Result.success("400", "不合法参数");
        } finally {
            // 关闭输入流和输出流
            if (bis != null) bis.close();
            if (bos != null) bos.close();
        }
    }

    /**
     * 删除文件 此方法只被调用
     *
     * @param fileId
     * @return
     */
    public boolean deleteFiles(Integer fileId) {
        // 要删除的文件路径
        String filePath = filesOssService.getFileUrl(fileId);
        // 创建 File 对象，表示要删除的文件
        File fileToDelete = new File(filePath);
        // 调用 delete() 方法尝试删除文件
        return fileToDelete.delete();
    }

    /**
     * 用户根据用户id删除文件
     *
     * @return
     */
    @RequestMapping("/delFileByUserId")
    public String deleteFileByUserId(FilesOss filesOss) {
        int i = filesOssService.deleteFileByUserId(filesOss);
        if (i > 0) {
            deleteFiles(filesOss.getFileID());
            return Result.success("200", "文件删除成功");
        } else {
            return Result.success("400", "文件删除失败");
        }
    }

    /**
     * 管理员根据文件id删除文件
     *
     * @param fileId
     * @return
     */
    @RequestMapping("/delFiles")
    public String deleteFile(Integer fileId) {
        int i = filesOssService.deleteFile(fileId);
        if (i > 0) {
            deleteFiles(fileId);
            return Result.success("200", "文件删除成功");
        } else {
            return Result.success("400", "文件删除失败");
        }
    }
}
